﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Reckoning
{
    /// <summary>
    /// Information about a counted word
    /// </summary>
    public class WordCountInfo
    {
        #region Properties
        /// <summary>
        /// For comparing against zero
        /// </summary>
        private const double SmallNumber = 1e-10;

        /// <summary>
        /// Rank of this word, set after sorting
        /// </summary>
        public int Rank { get; set; }

        /// <summary>
        /// The word, canonical form
        /// </summary>
        public string Word { get; private set; }        

        /// <summary>
        /// Number of occurrences of the word
        /// </summary>
        public uint Count { get; private set; }

        /// <summary>
        /// This word's count as a percentage of total words
        /// </summary>
        public double PercentageOfTotal { get; private set; }

        /// <summary>
        /// This word's percentage in the reference data
        /// </summary>
        public double ReferencePercentageOfTotal { get; private set; }

        /// <summary>
        /// Variants of the word
        /// </summary>
        private Dictionary<string, uint> _variants;
        public string Variants 
        {
            get
            {
                if (_variants.Count == 1)
                    return string.Empty;

                StringBuilder sb = new StringBuilder();                
                foreach (KeyValuePair<string, uint> pair in _variants)
                {
                    sb.AppendFormat("{0} ({1}), ", pair.Key, pair.Value);
                }

                sb.Remove(sb.Length - 2, 2);

                return sb.ToString();
            }
        }

        /// <summary>
        /// Ratio of percentage over the reference percentage
        /// </summary>
        public double Ratio 
        { 
            get 
            {
                double ret = 0.0;
                if (ReferencePercentageOfTotal > SmallNumber)
                    ret = PercentageOfTotal / ReferencePercentageOfTotal;

                return ret;
            }
        }        
        #endregion

        #region Methods
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="word">canonical form</param>
        /// <param name="variants">variants</param>
        /// <param name="count">count</param>
        /// <param name="pot">percentage</param>
        /// <param name="refPot">reference percentage</param>
        public WordCountInfo(string word, 
                             Dictionary<string, uint> variants, 
                             uint count, 
                             double pot, 
                             double refPot)
        {            
            Word = word;
            _variants = variants;
            Count = count;
            PercentageOfTotal = pot;
            ReferencePercentageOfTotal = refPot;
        }
        #endregion
    }

    /// <summary>
    /// Comparator class for WordCountInfo
    /// </summary>
    public class WordCountInfoComparer : IComparer<WordCountInfo>
    {
        /// <summary>
        /// Returns -1 if one should come before two,
        /// 1 if two should come before one, and 0 otherwise
        /// </summary>
        /// <param name="one">first thing</param>
        /// <param name="two">second thing</param>
        /// <returns></returns>
        public int Compare(WordCountInfo one, WordCountInfo two)
        {
            if (one.Count > two.Count)
                return -1;

            if (one.Count < two.Count)
                return 1;

            return (one.Word.CompareTo(two.Word));
        }
    }
}
